<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <link rel="stylesheet" type="text/css" href="style.css" />
    <title>m-validate</title>

</head>

<body>

<form id="myForm" name="myForm" novalidate>
    <div class="line">
        <label for="user">用户名：</label><input id="user" name="user" value="" placeholder="方贤正" />
    </div>
    <div class="line">
        <label for="password">登录密码：</label>
        <input id="password" name="password" type="password" maxlength="20" value=""/>
    </div>
    <div class="line field-item">
        <label for="confirm-password">确认密码：</label>
        <input id="confirm-password"  name="confirm-password" maxlength="20" type="password"
               value=""/>
    </div>
    <div class="line">
        <label for="mobile">手机号：</label><input id="mobile" name="mobile" value="138" />
    </div>
    <div class="line">
        <label for="email">邮箱：</label><input id="email" name="email" />
    </div>
    <div class="line">
        <label for="identityCard">身份证：</label><input id="identityCard" name="identityCard" />
    </div>
    <div class="line">
        <label for="age">年龄：</label><input id="age" name="age" />
    </div>
    <div class="line">
        <label for="sure">确定？</label><input type="checkbox" id="sure" name="sure" />
    </div>
    <div class="line">
        <label >性别：</label>
        <div class="sex">
            <label for="sex1">男：</label><input type="radio" id="sex1" name="sex" />
            <label for="sex2">女：</label><input type="radio" id="sex2" name="sex" />
        </div>

    </div>
    <div class="line">
        <input type="submit" id="submit" name="submit" value="提交" />
    </div>


</form>



<script>document.documentElement.style.fontSize = document.documentElement.clientWidth / 18.75 + 'px'</script>

<script src="m-validate.js"></script>

<script>

    (function(win, undefined){

        var regItem = {
            // 是否为必填
            required: function(field) {
                var value = field.value;

                //判断是不是单选框，多选框的可能
                if(field.type === 'checkbox' || field.type === 'radio'){
                    return field.checked === true;
                }
                return value !== null && value !== '';
            },
            maxLength: function(field, length){
                var value = field.value;
                return value.length <= length;
            },
            minLength: function(field, length){
                var value = field.value;
                return value.length >= length;
            }

        };

        var Mvalidate = function(form){
            this.form = document.forms[form];
            this.options = []
        };

        Mvalidate.prototype = {
            add: function(opts){

                var self = this;
                self.options.push(opts);
                return self;
            },
            remove: function(elem){
                var self = this, i = 0, j, len = self.options.length;

                for(; i < len; i++){
                    if(elem.trim() === self.options[i].name.trim()){
                        j = i;
                    }
                }
                self.options.splice(j,1);
                return self;
            },
            valid: function(){
                var self = this, i = 0, len = self.options.length;

                for(; i < len; i++){
                    if(validate.call(self, self.options[i]) === false){
                        return false;
                    }
                }

                return true;
            }

        };

        win.Mvalidate = Mvalidate;

        /*******私有方法**************************************/

        function validate(opts){
            var el = this.form[opts.name], i = 0;

            if(opts.rules){
                for(; i < opts.rules.length; i++){
                    var valiReg = true, valiStr = true;
                    if(typeof opts.rules[i] != 'string'){
                        valiReg = validateReg(el, opts.rules[i])
                    }else{
                        valiStr = validateString(el, opts.rules[i])
                    }

                    if(!valiReg || !valiStr){
                        alertMessage.call(this, opts, opts.message[i]);
                        return false;
                    }
                }
            }else if(opts.sameTo){
                var selfValue = el.value;
                var targetValue = this.form[opts.sameTo].value;
                if(selfValue !== targetValue){
                    alertMessage.call(this, opts, opts.message[i]);
                    return false;
                }
            }

            return true;
        }

        function alertMessage(opts, message){
            var errorEle = document.createElement('div');
            errorEle.className = 'errorMessage';
            var nodeEles = document.getElementsByClassName('errorMessage');

            if(nodeEles.length === 0){
                document.getElementsByTagName('body')[0].appendChild(errorEle);
            }
            var errEl = document.getElementsByClassName('errorMessage')[0];
            errEl.innerHTML = message;
            errorMessageStyle(errEl);
            if(opts.callback){
                opts.callback(this.form[opts.name], errEl)
            }
        }

        function errorMessageStyle(errEl){

            errEl.style.display = 'block';

            if(!/animated fadeOut/.test(errEl.className)){
                errEl.className += ' animated fadeOut';
            }

            errEl.addEventListener('webkitAnimationEnd',endAnime);
            errEl.addEventListener('animationend',endAnime);

            function endAnime(){
                removeClass(errEl,'animated');
                removeClass(errEl,'fadeOut');
                errEl.style.display = 'none'
            }

        }


        function validateReg(el, rule){
            return rule.test(el.value)
        }

        function validateString(el, rule){

            var result;
            var ruleArr = /(\w+)/ig.exec(rule);

            //不带参数的规则处理
            if(ruleArr[1] === ruleArr.input){
                result = regItem[ruleArr.input](el);

            }else{
                //带参数的规则处理，如：maxLength
                ruleArr = /(\w+)\((\d+)/ig.exec(rule);
                result = regItem[ruleArr[1]](el, ruleArr[2]);
            }
            return result
        }


        function removeClass(ele, oldClass){
            var classNames = ele.className.trim();
            classNames = classNames.replace(/\s+/g,' ');
            var classNameArr = classNames.split(' ');
            for(var j = 0; j<classNameArr.length; j++){
                if(oldClass === classNameArr[j]){
                    classNameArr.splice(j,1)
                }
            }
            return ele.className = classNameArr.join(' ');
        }
        function cssStyle(){
            var cssStyle = document.createElement('style');
            cssStyle.type = 'text/css';
            cssStyle.innerHTML = '.errorMessage{position:fixed;top:50%;right:0;left:0;display:block;margin:auto;padding:5%;width:60%;-webkit-border-radius:4px;background-color:rgba(0,0,0,.7);color:#fff;text-align:center;font-size:16px;transform:translateY(-50%);-ms-transform:translateY(-50%)}.animated{-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-fill-mode:both;animation-fill-mode:both}@-webkit-keyframes fadeOut{50%{opacity:1}to{opacity:0}}@keyframes fadeOut{50%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}';

            document.head.appendChild(cssStyle);
        }
        cssStyle();

    }(window));
    var ooo = new Mvalidate('myForm');
    ooo.add({
        name:'user',
        rules:['required',/^[\u2E80-\u9FFF]+$/,'maxLength(4)'],
        message:['用户名必须填写','用户名必须是中文','用户名最长不能超过4位'],
        callback:function(el, errorEl){

        }
    }).add({
        name:'password',
        rules:['required',/\d+/,'minLength(5)'],
        message:['密码必须填','密码必须为数字','密码太短'],
        callback:function(el, errorEl){

        }
    }).add({
        name:'confirm-password',
        sameTo:'password',
        message:['两次密码必须保持一致']
    }).add({
        name:'mobile',
        rules:[/^[1-9]\d{10}$/],
        message:['手机号输入错误']
    }).add({
        name:'email',
        rules:[/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/],
        message:['对不起，您填写的E-mail格式不正确！']
    }).add({
        name:'sure',
        rules:['required'],
        message:['确定项项必须选']
    })

    document.forms.myForm.submit.addEventListener('click',function(e){
        e.preventDefault();
        if(ooo.valid()){
            //在这里写Ajax提交
        }
    })


</script>

</body>
</html>